<!--
  * 内部费用单
  *
-->
<template>
  <a-drawer :title="formTitle" :open="visible" @close="onClose">
    <template #closeIcon>
      <close @on-close="onClose" />
    </template>
    <a-form ref="formRef" :model="form" :rules="rules" :label-col="{ sm: 4, lg: 6 }">
      <!---------- 基本信息 begin ----------->
      <a-card title="基本信息" class="smart-margin-bottom10">
        <a-row :gutter="{ sm: 8, md: 16, lg: 24 }">
          <a-col :xs="24" :lg="12" :xl="8" :xxl="6">
            <a-form-item label="单据时间" name="bill_date" required>
              <a-date-picker v-model:value="form.bill_date" style="width: 100%" valueFormat="YYYY-MM-DD" />
            </a-form-item>
          </a-col>
          <a-col :xs="24" :lg="12" :xl="8" :xxl="6">
            <a-form-item label="员工名称" name="related_user_id" required>
              <a-cascader v-model:value="form.related_user_id" :options="options" :load-data="loadData" placeholder="员工名称" change-on-select />
            </a-form-item>
          </a-col>
          <a-col :xs="24" :lg="12" :xl="8" :xxl="6">
            <a-form-item label="费用备注">
              <a-input v-model:value="form.remark" placeholder="请输入备注" />
            </a-form-item>
          </a-col>
        </a-row>
      </a-card>
      <!---------- 基本信息 end ----------->
      <!---------- 费用信息 begin ----------->
      <a-card title="费用信息" class="smart-margin-bottom10">
        <a-table size="small" :dataSource="form.detail" :columns="columns" :scroll="{ x: 'max-content' }" :pagination="false" :showSorterTooltip="false">
          <template #bodyCell="{ text, record, column, index }">
            <template v-if="column.dataIndex === 'index'">
              <div class="form-table-index">
                <span>{{ index + 1 }}</span>
                <div class="form-table-index-btn-wrap">
                  <div class="form-table-index-btn">
                    <div class="form-table-index-btn-item" @click="addFormDetail(index)">+</div>
                    <div class="form-table-index-btn-item" @click="delFormDetail(index)">-</div>
                  </div>
                </div>
              </div>
            </template>
            <template v-if="column.dataIndex === 'category_name'">
              <a-form-item class="form-table-item" required :name="['detail', index, 'category_name']" :rules="[{ required: true, message: '请添加费用类别', validator: (rule, value, callback) => validatorGoodsTable(record, rule, value, callback) }]">
                <!-- 使用 a-tooltip 显示-->
                <a-tooltip v-if="text">
                  <template #title>{{ text }}</template>
                  <a-input :value="text" readonly placeholder="请输入费用类别" size="small">
                    <template #suffix>
                      <a-button @click="showGoodsSelectModal(index)" type="link">多选</a-button>
                    </template>
                  </a-input>
                </a-tooltip>
                <a-input :value="text" readonly placeholder="请输入费用类别" size="small" v-else>
                  <template #suffix>
                    <a-button @click="showGoodsSelectModal(index)" type="link">多选</a-button>
                  </template>
                </a-input>
              </a-form-item>
            </template>
            <template v-if="column.dataIndex === 'amount'">
              <a-form-item class="form-table-item" required :name="['detail', index, 'amount']" :rules="[{ required: true, message: '请输入金额' }]">
                <a-input-number v-model:value="record.amount" :min="0" placeholder="请输入金额" />
              </a-form-item>
            </template>
            <template v-if="column.dataIndex === 'remark'">
              <a-form-item class="form-table-item">
                <a-input v-model:value="record.remark" placeholder="请输入备注" />
              </a-form-item>
            </template>
          </template>
        </a-table>
      </a-card>
      <!---------- 费用信息 end ----------->
    </a-form>
    <CostSelectModal ref="CostSelectModalRef" @confirm="onSelectGoods" />
    <template #footer>
      <div class="smart-table-operate-block" style="display: flex; gap: 8px">
        <a-button @click="onClose">取消</a-button>
        <a-button type="primary" @click="onSubmit">提交</a-button>
      </div>
    </template>
  </a-drawer>
</template>
<script setup lang="ts">
import { message } from 'ant-design-vue'
import { useLoadingStore } from '@/store/modules/loading-store'
import _ from 'lodash'
import { errorSentry } from '@/lib/error-sentry'
import { searchApi } from '@/api/search/search-api'
import { expenseApi } from '@/api/business/finance/cost-api'
import CostSelectModal from './cost-select-modal.vue'
import { useUserStore } from '@/store/modules/user-store'
const { getUserInfo } = useUserStore()
const userInfo = getUserInfo
const loadingStore = useLoadingStore()
// emit
const emit = defineEmits(['reloadList'])
// 组件ref
const formRef = ref()

const formDefault = {
  // 单据时间
  bill_date: '',
  // 员工类型
  related_user_type: '',
  // 员工id
  related_user_id: [],
  // 总计
  amount: '',
  // 备注
  remark: '',
  // 费用信息
  detail: []
}
const form = ref({ ...formDefault })

const options = ref([
  {
    value: 1,
    label: '业务员',
    isLeaf: false
  },
  {
    value: 2,
    label: '用户',
    isLeaf: false
  }
])

onMounted(() => {
  form.value.detail.push({})
})
const rules = {
  bill_date: [{ required: true, message: '请选择单据时间', trigger: 'change' }],
  related_user_id: [{ required: true, message: '请选择员工', trigger: 'change' }]
}

// 费用表格自定义校验
const validatorGoodsTable = (rowData, rule, value, callback) => {
  if (_.isEmpty(rowData) || !_.isNil(value)) callback()
  else {
    callback(rule.message)
  }
}

// 是否展示抽屉
const visible = ref(false)
function showDrawer(rowData) {
  form.value = _.cloneDeep(formDefault)
  if (rowData.id && !_.isEmpty(rowData)) {
    form.value = _.pick(rowData, ['id', ...Object.keys(formDefault)])
    form.value.related_user_id = [rowData.related_user_type, rowData.related_user_id]
    loadData([{ value: rowData.related_user_type, label: '', isLeaf: false, loading: true }])
    // 加载详情数据
    form.value.detail = rowData.details.map((item) => {
      return {
        ...item,
        category_name: item.category.category_name
      }
    })
  }
  visible.value = true
  nextTick(() => {
    formRef.value.clearValidate()
  })
}

function onClose() {
  form.value = formDefault
  deletedGoods.value = []
  visible.value = false
}

async function onSubmit() {
  if (_.filter(unref(form).detail, (item) => !_.isEmpty(item)).length === 0) {
    message.error('请选择费用类别')
    return
  }
  // 去除空行
  unref(form).detail = _.filter(unref(form).detail, (item) => {
    return !_.every(item, (value) => value === null)
  })
  await nextTick()
  formRef.value
    .validate()
    .then(async () => {
      loadingStore.show()
      try {
        if (unref(form).id) {
          const totalAmount = _.sumBy(unref(form).detail, 'amount')
          const keys = ['category_id', 'amount', 'remark']
          const specData = _(unref(form).detail)
            .concat(deletedGoods.value)
            .cloneDeep()
            .map((item) => {
              const result = _.pick(item, keys)
              return result
            })
          const data = {
            id: unref(form).id,
            related_user_type: unref(form).related_user_id[0],
            related_user_id: unref(form).related_user_id[1],
            bill_date: unref(form).bill_date,
            remark: unref(form).remark,
            amount: totalAmount,
            detail: specData
          }
          await expenseApi.editExpense(data)
        } else {
          const totalAmount = _.sumBy(unref(form).detail, 'amount')
          const keys = ['category_id', 'amount', 'remark']
          const specData = _(unref(form).detail)
            .cloneDeep()
            .map((item) => {
              return {
                ..._.pick(item, keys)
              }
            })
          const data = {
            related_user_type: unref(form).related_user_id[0],
            related_user_id: unref(form).related_user_id[1],
            bill_date: unref(form).bill_date,
            remark: unref(form).remark,
            amount: totalAmount,
            detail: specData
          }
          await expenseApi.addExpense(data)
        }
        message.success('操作成功')
        onClose()
        emit('reloadList')
      } catch (error) {
        message.error(error.msg)
        errorSentry.captureError(error)
      } finally {
        loadingStore.hide()
      }
    })
    .catch((error) => {
      console.log('error', error)
      message.error('参数验证错误，请仔细填写表单数据!')
    })
}

defineExpose({
  showDrawer
})

// ----------------------------------  基本信息 begin  ----------------------------------

const loadData = (selectedOptions) => {
  const targetOption = selectedOptions[selectedOptions.length - 1]
  targetOption.loading = true
  setTimeout(async () => {
    // 根据二级选项的值调用不同的接口
    if (targetOption.value === 1) {
      // 调用业务员相关的接口
      const res = await searchApi.salesmanList()
      options.value[0].children = res.data.map((val) => {
        return {
          value: val.id,
          label: val.rename
        }
      })
      targetOption.loading = false
    } else if (targetOption.value === 2) {
      options.value[1].children = [
        {
          value: userInfo.id,
          label: userInfo.username
        }
      ]
      targetOption.loading = false
    }
  }, 500)
}

// ----------------------------------  基本信息 end  ----------------------------------

// 选择弹窗
const CostSelectModalRef = ref()
const modalIndex = ref(0)
// 记录点击多选按钮的表格行索引，插入数据时使用
function showGoodsSelectModal(index: number) {
  modalIndex.value = index
  CostSelectModalRef.value.showModal()
}

// 记录已删除的
const deletedGoods = ref([])

// 选择回调
function onSelectGoods(goodsList) {
  if (goodsList.length === 0) return
  // 处理数据
  function handleGoodsData(rowData) {
    const keys = ['category_name']
    return {
      ..._.pick(rowData, keys),
      category_id: rowData.id
    }
  }
  // 如果当前索引值有数据则覆盖
  const rows = _.map(goodsList, handleGoodsData)
  if (unref(form).detail[modalIndex.value]) {
    if (unref(form).detail[modalIndex.value].id) {
      deletedGoods.value.push(form.value.detail[modalIndex.value])
    }
    form.value.detail.splice(modalIndex.value, 1, ...rows)
  } else {
    // 否则插入数据
    if (modalIndex.value === 0) {
      // 从modalIndex插入数据
      form.value.detail.splice(modalIndex.value, 0, ...rows)
    } else {
      // 从modalIndex插入数据
      form.value.detail.splice(modalIndex.value + 1, 0, ...rows)
    }
  }
  // 自动追加一个空行
  if (!_.isEmpty(_.last(unref(form).detail))) form.value.detail.push({})
}

// ----------------------------------  商品信息  ----------------------------------
// 表头配置
const columns = [
  {
    title: '序号',
    dataIndex: 'index'
  },
  {
    title: '费用类别',
    dataIndex: 'category_name'
  },
  {
    title: '费用金额(元)',
    dataIndex: 'amount'
  },
  {
    title: '类别备注',
    dataIndex: 'remark'
  }
]
// 增加空行
function addFormDetail(index: number) {
  form.value.detail.splice(index + 1, 0, {})
}
// 删除行
const delFormDetail = (index: number) => {
  const formDetail = unref(form).detail
  const item = formDetail[index]

  // 检查是否只剩最后一条数据
  if (formDetail.length === 1) {
    message.error('不能删除最后一条数据！')
    return
  }
  // 直接执行删除操作
  executeDelete(formDetail, item, index)
}

// 执行删除操作的函数
const executeDelete = (formDetail, item, index) => {
  // 如果是编辑状态，将删除的项加入已删除列表
  if (unref(form).id && item.id) {
    deletedGoods.value.push(item)
  }

  // 删除指定索引的元素
  formDetail.splice(index, 1)
  message.success('删除成功')
}

// 表单标题
const formTitle = computed(() => (form.value.id ? '编辑' : '新增'))
</script>
<style scoped lang="less">
.form-table-item {
  margin-bottom: 0;
  max-width: 100%;
}
.form-table-index {
  width: 100%;
  height: 100%;
  overflow: hidden;
  text-align: center;
  .form-table-index-btn-wrap {
    display: none;
  }
  .form-table-index-btn {
    display: flex;
  }
  .form-table-index-btn-item {
    width: 50%;
    height: 100%;
    font-size: 14px;
    font-weight: bold;
    text-align: center;
    cursor: pointer;
    user-select: none;
  }
  .form-table-index-btn-item:hover {
    background: #f87171ff;
    color: white;
  }
}
.form-table-index:hover span {
  display: none;
}
.form-table-index:hover .form-table-index-btn-wrap {
  display: block;
}
</style>
